package com.example.account.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.example.account.mapper.AccountMapper;
import com.example.account.service.AccountDetailService;
import com.example.account.service.AccountService;
import com.example.commons.exception.BusinessException;
import com.example.commons.inspect.ParamsInspect;
import com.example.commons.math.Decimal;
import com.example.commons.time.TimeTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Service
public class AccountServiceImpl implements AccountService {
    @Autowired
    AccountMapper accountMapper;
    @Autowired
    AccountDetailService accountDetailService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addAccount(String userId) {
        ParamsInspect.IsNull(userId, "用户ID");
        if (1 != accountMapper.addAccount(userId, TimeTools.getTime())) {
            throw new BusinessException("添加失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void operBal(String userId, String balance, int payType, int type, String remarks, String explains) {
        Map<String, Object> map = this.selectUserAccount(userId);
        balance = new BigDecimal(balance).abs().toPlainString();
        if ((payType == 2)) {
            sub(userId, balance, map);
        } else if ((payType == 1)) {
            add(userId, balance);
        } else {
            throw new BusinessException("未知类型");
        }
        Map<String, Object> afterMap = this.selectUserAccount(userId);
        accountDetailService.addAccountDetail(userId, balance, String.valueOf(afterMap.get("balance")), payType, type, remarks, explains);
    }

    public void sub(String userId, String balance, Map<String, Object> accountMap) {
        String subBal = new BigDecimal(String.valueOf(accountMap.get("balance"))).subtract(new BigDecimal(balance)).toPlainString();
        if (-1 == Decimal.bigOrSmall(subBal, "0")) {
            throw new BusinessException("余额不足");
        }
        balance = new BigDecimal("0").subtract(new BigDecimal(balance)).toPlainString();
        if (1 != accountMapper.operBal(userId, balance)) {
            throw new BusinessException("操作失败");
        }
    }

    public void add(String userId, String balance) {
        if (1 != accountMapper.operBal(userId, balance)) {
            throw new BusinessException("操作失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Async
    public JSONObject selectUserAccount(String userId) {
        JSONObject map = accountMapper.selectUserAccount(userId);
        if (null == map) {
            this.addAccount(userId);
            map = new JSONObject();
            map.put("user_id", userId);
            map.put("balance", 0);
        }
        return map;
    }
}
